package com.svms.indent;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.metainfo.ComponentInfo;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.svms.service.constants.SvmsStatusCodes;
import com.svms.service.vo.SpareCodesVO;
import com.svms.service.vo.VehicleSpareVO;
import com.svms.service.vo.VehicleVO;
import com.svms.sparedetails.ManageSpareDetailCtrl;
import com.svms.utils.SvmsMessageUtils;
import com.svms.utils.SvmsWindowUtils;
import com.svms.web.constants.SvmsResources;
import com.svms.web.factory.SvmsWebFactory;

/**
 * 
 */

/**
 * @author om39a
 * 
 */
public class BillItemDialogueCtrl extends GenericForwardComposer {

	private Window window_bill_item_dialogue;

	private Button btn_close;
	private Button btn_cancle;
	private Button btn_save_bill_item;
	private Button btn_edit_bill_item;
	private Button btn_delete_bill_item;
	private Button btn_add_bill_item;
	private Button btn_add_spare;

	private Textbox txb_spare_item_cost;
	private Textbox txb_invoice_number;
	private Datebox dtb_instalation_date;

	private Listbox lstbx_spares;
	private Listbox lstbx_vehicles;

	private ListModelList<VehicleVO> lst_model_vehicles;
	private ListModelList<SpareCodesVO> lst_model_sparecodes;

	private VehicleSpareVO vehicleSpareVO;
	private VehicleSpareVO oldVehicleSpareVO;
	private VehicleSpareVO vehicleSpareOfIndent;

	private IndentDialogueCtrl indentDialogueCtrl;

	public VehicleSpareVO getVehicleSpareVO() {
		return vehicleSpareVO;
	}

	public void setVehicleSpareVO(VehicleSpareVO vehicleSpareVO) {
		this.vehicleSpareVO = vehicleSpareVO;
	}

	public VehicleSpareVO getOldVehicleSpareVO() {
		return oldVehicleSpareVO;
	}

	public void setOldVehicleSpareVO(VehicleSpareVO oldVehicleSpareVO) {
		this.oldVehicleSpareVO = (VehicleSpareVO) SerializationUtils
				.clone(oldVehicleSpareVO);
	}

	@Override
	public ComponentInfo doBeforeCompose(Page page, Component parent,
			ComponentInfo compInfo) {
		// TODO Auto-generated method stub
		return super.doBeforeCompose(page, parent, compInfo);
	}

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		EventQueues.lookup("spareChangeEventQueue", EventQueues.DESKTOP, true)
				.subscribe(new EventListener<Event>() {

					@Override
					public void onEvent(Event event) throws Exception {
						System.out.println("Event spareChange Invoked");

						loadListBoxDetails();

						// refreshVehicleAlertsList();
						// onCreate$window_main_alerts();
					}
				});
	}

	/**
	 * Operation to be performed on load of the window.
	 * 
	 * @param event
	 * @throws Exception
	 */
	public void onCreate$window_bill_item_dialogue(Event event)
			throws Exception {

		Map<String, Object> args = SvmsWindowUtils.getCreationArgsMap(event);

		loadListBoxDetails();

		vehicleSpareOfIndent = (VehicleSpareVO) args.get("selectedBillItem");

		vehicleSpareVO = (VehicleSpareVO) SerializationUtils
				.clone(vehicleSpareOfIndent);
		indentDialogueCtrl = (IndentDialogueCtrl) args
				.get("indentDialogueCtrl");
		
		if (getVehicleSpareVO() == null) {
			// Which means edit in progress. So enable fields to edit
			txb_invoice_number.setValue(indentDialogueCtrl.getTxb_invoice_number().getValue());
			newVehicleSpare();
			loadAddEditScenarioButtons();
			enableDefaultFields();

		} else {
			setOldVehicleSpareVO(getVehicleSpareVO());
			writeBeanToDialogue(getOldVehicleSpareVO());
			loadDefalutScenarioButtons();
			disableDefalutFields();

		}

	}

	private void loadListBoxDetails() {

		System.out.println("--->>>> " + "loadListBoxDetails");

		lst_model_vehicles = new ListModelList<VehicleVO>(SvmsWebFactory
				.vehicleService().getVehicleList());
		lst_model_sparecodes = new ListModelList<SpareCodesVO>(SvmsWebFactory
				.spareDetailsService().getAllSparesDetailsList());
		
		lstbx_vehicles.setModel(lst_model_vehicles);
		lstbx_spares.setModel(lst_model_sparecodes);
		
		System.out.println(lst_model_vehicles);
		System.out.println(lst_model_sparecodes);

		lstbx_vehicles.setMold("select");
		lstbx_spares.setMold("select");

		lstbx_vehicles.setItemRenderer(new ListitemRenderer<VehicleVO>() {

			@Override
			public void render(Listitem item, VehicleVO data, int index)
					throws Exception {

				Listcell listcell = new Listcell(data.getVehicleNumber());
				listcell.setParent(item);

				item.setAttribute("selecteVehicle", data);
			}

		});

		lstbx_spares.setItemRenderer(new ListitemRenderer<SpareCodesVO>() {

			@Override
			public void render(Listitem item, SpareCodesVO data, int index)
					throws Exception {

				Listcell listcell = new Listcell(data.getSpareName());
				listcell.setParent(item);

				item.setAttribute("selectedSpare", data);
			}

		});

	}

	private void newVehicleSpare() {
		VehicleSpareVO vehicleSpareVO = new VehicleSpareVO();
		vehicleSpareVO.setSpareCodes(new SpareCodesVO());
		setVehicleSpareVO(vehicleSpareVO);
		writeBeanToDialogue(getVehicleSpareVO());

	}

	/**
	 * Operation to be performed on click of add spare button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_add_spare(Event event) {
		showDetailView();
	}

	/**
	 * Operation to be performed on click of add spare button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_add_bill_item(Event event) {
		oldVehicleSpareVO = null;
		newVehicleSpare();
		enableDefaultFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of edit button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_edit_bill_item(Event event) {
		enableDefaultFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_cancle(Event event) {
		writeBeanToDialogue(oldVehicleSpareVO);
		setVehicleSpareVO(oldVehicleSpareVO);
		disableDefalutFields();
		loadDefalutScenarioButtons();
	}

	public void onClick$btn_close(Event event) {
		setVehicleSpareVO(oldVehicleSpareVO);
		window_bill_item_dialogue.detach();
	}

	/**
	 * Operation to be performed on click of save button. It performs the save
	 * operation. It will loadDefalutScenarioButtons and disables all editable
	 * fields on successful save
	 * 
	 * @param event
	 */
	public void onClick$btn_save_bill_item(Event event) {
		doSave();
	}

	/**
	 * Save operation by calling save method from service
	 */
	private void doSave() {

		writeDialogueToBean();

		// Uncomment when adding service call for movement

		/*
		 * if (movementVO.getResultCode().getErrorDetails().size() > 0) {
		 * SvmsMessageUtils.showErrorMessageFromLable(movementVO
		 * .getResultCode().getErrorDetails());
		 * writeBeanToDialogue(getOldMovementVO()); return; }
		 */

		if (false) {

		} else {

			if (indentDialogueCtrl != null
					&& indentDialogueCtrl.getLstbx_bill_items() != null) {

				// now synchronize the customer listBox
				ListModelList lml = (ListModelList) indentDialogueCtrl
						.getLstbx_bill_items().getListModel();

				// Check if the customer object is new or updated
				// -1 means that the obj is not in the list, so it's new.
				System.out.println("oldSpareCodesVO " + oldVehicleSpareVO);
				System.out.println("getSpareCodeVO " + vehicleSpareVO);
				if (lml.indexOf(oldVehicleSpareVO) == -1) {
					lml.add(getVehicleSpareVO());
					System.out.println("Add bill item to main vehicle list");
					setOldVehicleSpareVO(getVehicleSpareVO());
				} else {
					lml.set(lml.indexOf(getOldVehicleSpareVO()),
							getVehicleSpareVO());
					System.out.println("save bill item to main vehicle list");
					setOldVehicleSpareVO(getVehicleSpareVO());
				}

			}
			SvmsMessageUtils
					.showSuccessMessage("Bill Item Detail Was successfully saved to the system");
			disableDefalutFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox

	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_delete_bill_item(Event event) {

		writeDialogueToBean();

		SpareCodesVO spareCodesVO;

		if (getVehicleSpareVO() != null
				&& getVehicleSpareVO().getVehicleSpareId() != null) {

		} else {
			SvmsMessageUtils
					.showErrorMessageFromLable("Select Bill Item to delete");
			return;
		}

		/*
		 * if (getMovementVO().getResultCode().getErrorDetails().size() > 0) {
		 * SvmsMessageUtils.showErrorMessageFromLable(vehicleVO
		 * .getResultCode().getErrorDetails()); return; }
		 */

		if (false) {
		} else {
			SvmsMessageUtils
					.showSuccessMessage("Bill Item Detail Was successfully deleted from the System");
			disableDefalutFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox
		if (indentDialogueCtrl != null
				&& indentDialogueCtrl.getLstbx_bill_items() != null) {

			// now synchronize the customer listBox
			final ListModelList lml = (ListModelList) indentDialogueCtrl
					.getLstbx_bill_items().getListModel();

			// Check if the customer object is new or updated
			// -1 means that the obj is not in the list, so it's new.
			if (lml.indexOf(getOldVehicleSpareVO()) == -1) {
				System.out
						.println("Bill item Detail not present in main Movement list");
			} else {
				lml.remove(getOldVehicleSpareVO());
				System.out
						.println("Removed bill item Detail from main Movement list");
			}

		}
		window_bill_item_dialogue.detach();
	}

	private void writeDialogueToBean() {

		if (vehicleSpareVO != null) {
			
			vehicleSpareVO.setVehicleSpareCost(txb_spare_item_cost.getValue());
			vehicleSpareVO.setInstallationDate(dtb_instalation_date.getValue());
			vehicleSpareVO.setInvoiceNumber(txb_invoice_number.getValue());

			Listitem selecteVehicle = lstbx_vehicles.getSelectedItem();
			vehicleSpareVO.setVehicleVO((VehicleVO) selecteVehicle
					.getAttribute("selecteVehicle"));
			Listitem selectedSpare = lstbx_spares.getSelectedItem();
			System.out
					.println("(SpareCodesVO) selectedSpare.setAttribute(\"selectedSpare\") "
							+ (SpareCodesVO) selectedSpare
									.getAttribute("selectedSpare"));
			vehicleSpareVO.setSpareCodes((SpareCodesVO) selectedSpare
					.getAttribute("selectedSpare"));
		}

	}

	private void writeBeanToDialogue(VehicleSpareVO vehicleSpareVO) {

		if (vehicleSpareVO != null) {
			txb_spare_item_cost.setValue(vehicleSpareVO.getVehicleSpareCost());
			dtb_instalation_date.setValue(vehicleSpareVO.getInstallationDate());

			lstbx_vehicles.setSelectedIndex(lst_model_vehicles
					.indexOf(vehicleSpareVO.getVehicleVO()));
			lstbx_spares.setSelectedIndex(lst_model_sparecodes
					.indexOf(vehicleSpareVO.getSpareCodes()));
		}

	}

	/**
	 * Opens the detail view of the Vehicle Controller. <br>
	 * Overhanded some params in a map if needed. <br>
	 * 
	 * @param branche
	 * @throws Exception
	 */
	private void showDetailView() {

		final HashMap<String, Object> map = new HashMap<String, Object>();

		Window win = null;

		try {
			win = (Window) Executions.createComponents(
					SvmsResources.MANAGE_SPARE_DIALOGUE, null, map);
		} catch (final Exception e) {
			e.printStackTrace();
			SvmsMessageUtils.showErrorMessage(e.getMessage());
			if (win != null) {
				win.detach();
			}
		}
	}

	private void loadAddEditScenarioButtons() {

		btn_add_spare.setDisabled(false);

		btn_add_bill_item.setDisabled(true);
		btn_delete_bill_item.setDisabled(true);
		btn_edit_bill_item.setDisabled(true);
		btn_save_bill_item.setDisabled(false);

		btn_cancle.setDisabled(false);
		btn_close.setDisabled(false);

	}

	private void enableDefaultFields() {

		txb_spare_item_cost.setDisabled(false);
		txb_invoice_number.setDisabled(true);
		lstbx_spares.setDisabled(false);
		lstbx_vehicles.setDisabled(false);

	}

	private void disableDefalutFields() {

		txb_spare_item_cost.setDisabled(true);
		txb_invoice_number.setDisabled(true);
		lstbx_spares.setDisabled(true);
		lstbx_vehicles.setDisabled(true);

	}

	/**
	 * Will load DEFAULT CURD buttons. Is same for DEFALUT, SAVE, DISCARD
	 */
	private void loadDefalutScenarioButtons() {

		btn_add_spare.setDisabled(true);

		btn_add_bill_item.setDisabled(false);
		btn_delete_bill_item.setDisabled(false);
		btn_edit_bill_item.setDisabled(false);
		btn_save_bill_item.setDisabled(true);

		btn_cancle.setDisabled(true);
		btn_close.setDisabled(false);
	}

}
